package org.thrj.wechat.sdk.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.thrj.wechat.sdk.WeChatCommonSdk;
import org.thrj.wechat.entity.UserSusceptibleInfo;
import org.thrj.wechat.entity.WeChatAccessToken;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@ConditionalOnProperty({"wx.appid", "wx.appSecret"})
public class WeChatCommonSdkImpl implements WeChatCommonSdk {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appSecret}")
    private String appSecret;

    public String getAccessToken() {
        // 查询redis中是否有access_token
        String accessToken = (String) redisTemplate.opsForValue().get("wx::access_token");
        if (accessToken == null) {
            // 通过微信官方API获取access_token
            WeChatAccessToken WeChatAccessToken = restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appSecret, WeChatAccessToken.class);
            // 检查返回结果是否不为空
            if (WeChatAccessToken == null) {
                throw new RuntimeException("获取access_token失败");
            }
            accessToken = WeChatAccessToken.getAccess_token();
            // redis中缓存access_token，并设置过期时间(单位为秒)
            redisTemplate.opsForValue().set("wx::access_token", accessToken, WeChatAccessToken.getExpires_in(), TimeUnit.SECONDS);
        }
        return accessToken;
    }

    @Override
    public UserSusceptibleInfo getUserSusceptibleInfo(String code) {
        // 拼接微信提供的用来换取openid的url
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code&connect_redirect=1", appid, appSecret, code);
        // 使用RestTemplate发送Https请求
        return restTemplate.getForObject(url, UserSusceptibleInfo.class);
    }

    @Override
    public void msgSecCheck(Integer scene, String openid, String content) {
        // 构建请求体数据（使用 Map 作为载体）
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("openid", openid);
        requestBody.put("scene", scene);
        requestBody.put("version", 2);
        requestBody.put("content", content);
        // 设置请求头（Content-Type 为 application/json）
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        ObjectMapper objectMapper = new ObjectMapper();
        String body = null;
        try {
            body = objectMapper.writeValueAsString(requestBody);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("请求参数异常");
        }
        headers.setContentLength(body.getBytes(StandardCharsets.UTF_8).length);
        // 发送 POST 请求，接收响应
        ResponseEntity<String> response = restTemplate.postForEntity("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + getAccessToken(), new HttpEntity<>(requestBody, headers), String.class);
        Map<String, Object> responseBody = null;
        try {
            responseBody = objectMapper.readValue(response.getBody(), Map.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("响应体解析错误");
        }
        if (Objects.equals((String) responseBody.get("errmsg"), "ok")) {
            Map<String, Object> result = (Map<String, Object>) responseBody.get("result");
            Integer label = (Integer) result.get("label");
            if (label == 100) {
                // 正常
            } else if (label == 10001) {// 广告
                throw new RuntimeException("广告内容，请重新发布");
            } else if (label == 20001) {// 时政
                throw new RuntimeException("包含时政内容，请重新发布");
            } else if (label == 20002) {// 色情
                throw new RuntimeException("包含色情内容，请重新发布");
            } else if (label == 20003) {// 辱骂
                throw new RuntimeException("包含辱骂内容，请重新发布");
            } else if (label == 20006) {// 违法犯罪
                throw new RuntimeException("包含违法犯罪内容，请重新发布");
            } else if (label == 20008) {// 欺诈
                throw new RuntimeException("包含欺诈内容，请重新发布");
            } else if (label == 20012) { // 低俗
                throw new RuntimeException("包含低俗内容，请重新发布");
            } else if (label == 20013) {// 版权
                throw new RuntimeException("包含版权内容，请重新发布");
            }
        }
    }

}
